<template>
  <el-dialog
    v-model="dialogVisible"
    class="edit-dialog"
    width="592px"
    @closed="handleDialogClose"
  >
    <div class="dialog-header">
      {{ operationTypre == 'add' ? '新增' : '编辑' }}
    </div>
    <div class="dialog-content" v-if="category == 'user'">
      <el-form :model="form" label-width="auto" style="max-width: 600px">
        <div class="row" v-if="operationTypre == 'add'">
          <el-form-item label="账号">
            <el-input v-model="addForm.userName" placeholder="账号" />
          </el-form-item>
          <el-form-item label="密码">
            <el-input v-model="addForm.password" placeholder="密码" />
          </el-form-item>
        </div>
        <div class="row">
          <el-form-item label="用户">
            <el-input v-model="form.nickName" placeholder="用户名" />
          </el-form-item>
          <el-form-item label="手机号">
            <el-input v-model="form.phonenumber" placeholder="手机号" />
          </el-form-item>
        </div>
        <div class="row">
          <el-form-item label="邮箱">
            <el-input v-model="form.email" placeholder="邮箱" />
          </el-form-item>
          <el-form-item label="性别">
            <el-select v-model="form.sex" @change="sexChange">
              <el-option
                v-for="(item, index) in sexOption"
                :key="index"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </div>
        <div class="row">
          <el-form-item label="状态" v-if="operationTypre == 'edit'">
            <el-select v-model="form.status" @change="statusChange">
              <el-option
                v-for="(item, index) in statusOption"
                :key="index"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </div>
        <div class="row multipleRow">
          <el-form-item label="角色">
            <el-select v-model="form.roleIds" multiple @change="selectChange">
              <el-option
                v-for="(item, index) in rowData"
                :key="index"
                :label="item.roleName"
                :value="item.roleId"
              />
            </el-select>
          </el-form-item>
        </div>
        <div class="row multipleRow" v-if="operationTypre == 'edit'">
          <el-form-item label="备注">
            <el-input v-model="form.remark" placeholder="备注" />
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="dialog-content" v-if="category == 'role'">
      <el-form :model="form" label-width="auto" style="max-width: 600px">
        <div class="row">
          <el-form-item label="角色名称">
            <el-input v-model="roleFrom.roleName" placeholder="角色名称" />
          </el-form-item>
          <el-form-item label="排序">
            <el-input v-model="roleFrom.roleSort" placeholder="排序" />
          </el-form-item>
        </div>
        <div class="row">
          <el-form-item label="角色标识">
            <el-input v-model="roleFrom.roleKey" placeholder="角色标识" />
          </el-form-item>
          <el-form-item label="状态" v-if="operationTypre == 'add'">
            <el-select v-model="roleFrom.status" @change="statusChange">
              <el-option
                v-for="(item, index) in statusOption"
                :key="index"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </div>
        <div class="row multipleRow">
          <el-form-item label="授权">
            <div class="authorization">
              <ul>
                <li
                  v-for="(item, index) in threeData"
                  :key="item.id"
                  class="parent"
                >
                  <img
                    src="./images/icon.png"
                    alt=""
                    class="icon"
                    @click="toggleExpand(item)"
                    :style="{
                      transform: item.expanded
                        ? 'rotate(0deg)'
                        : 'rotate(-90deg)'
                    }"
                  />
                  <div class="parentCheck" @click="parentClick(item)">
                    <img
                      v-if="!item.check"
                      src="./images/check1.png"
                      alt=""
                      class="checkout"
                    />
                    <img
                      v-if="item.check"
                      src="./images/check2.png"
                      alt=""
                      class="checkout"
                    />
                  </div>

                  <label @click="toggleExpand(item)">{{ item.label }}</label>
                  <ul v-if="item.expanded" class="children">
                    <li
                      v-for="(child, ind) in item.children"
                      :key="child.id"
                      style="cursor: pointer"
                    >
                      <img
                        src="./images/icon.png"
                        alt=""
                        class="icon"
                        v-if="child.children"
                        @click="toggleExpand(child)"
                        :style="{
                          transform: child.expanded
                            ? 'rotate(0deg)'
                            : 'rotate(-90deg)'
                        }"
                      />
                      <div
                        class="parentCheck"
                        @click="chilrenClick(item, child)"
                      >
                        <img
                          v-if="!child.check"
                          src="./images/check1.png"
                          alt=""
                          class="checkout"
                        />
                        <img
                          v-if="child.check"
                          src="./images/check2.png"
                          alt=""
                          class="checkout"
                        />
                      </div>

                      <label @click="toggleExpand(child)">{{
                        child.label
                      }}</label>
                      <ul v-if="child.expanded" class="children">
                        <li
                          v-for="(val, ind) in child.children"
                          :key="val.id"
                          style="cursor: pointer"
                          @click="sonClick(child, val, item)"
                        >
                          <img
                            v-if="!val.check"
                            src="./images/check1.png"
                            alt=""
                            class="checkout"
                          />
                          <img
                            v-if="val.check"
                            src="./images/check2.png"
                            alt=""
                            class="checkout"
                          />
                          <label>{{ val.label }}</label>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </div>
          </el-form-item>
        </div>
        <div class="row multipleRow">
          <el-form-item label="备注">
            <el-input v-model="roleFrom.remark" placeholder="备注" />
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="dialog-bottom">
      <div @click="sure">确认</div>
      <div @click="handleDialogClose">取消</div>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import apiList from '@/pages/system/api/api'
import { ElMessage } from 'element-plus'
const dialogVisible = ref(false)
const expanded = ref(false)
const category = ref()
const operationTypre = ref()
const defaultKeys = ref([])
const form = ref({
  nickName: '',
  phonenumber: '',
  sex: '',
  status: '',
  roleIds: '',
  remark: '',
  email: '',
  userId: '',
  userName: ''
})
const addForm = ref({
  email: '',
  nickName: '',
  password: '',
  phonenumber: '',
  roleIds: '',
  sex: '',
  userName: ''
})
const roleFrom = ref({
  roleName: '',
  roleSort: '',
  roleId: '',
  roleKey: '',
  status: '',
  remark: '',
  menuIds: []
})
const propsObj = ref({
  label: 'label',
  children: 'children'
})
const threeData = ref([])
const sexOption = ref([
  {
    name: '男',
    value: 0
  },
  {
    name: '女',
    value: 1
  }
])
const statusOption = ref([
  {
    name: '正常',
    value: 0
  },
  {
    name: '停用',
    value: 1
  }
])

const rowData = ref([])
const getRolelistData = () => {
  apiList.getRolelist().then(res => {
    rowData.value = res.rows
  })
}
const selectChange = data => {
  form.value.roleIds = data
}
const sexChange = data => {
  form.value.sex = data
}
const statusChange = data => {
  form.value.status = data
  roleFrom.value.status = data
}
const checkChildren = node => {
  if (node.children) {
    node.children.forEach(child => {
      child.check = node.check
      checkChildren(child)
    })
  }
}
const checkedIds = ref([])
const collectCheckedIds = node => {
  if (node.check) {
    checkedIds.value.push(node.id)
  }
  // 递归处理子节点
  if (node.children && node.children.length > 0) {
    for (let child of node.children) {
      collectCheckedIds(child)
    }
  }
}

const toggleExpand = data => {
  data.expanded = !data.expanded
}
//一级
const parentClick = data => {
  data.check = !data.check
  checkedIds.value = []
  checkChildren(data)
  for (let item of threeData.value) {
    collectCheckedIds(item)
  }
  roleFrom.value.menuIds = checkedIds.value
}
//二级
const chilrenClick = (item, data) => {
  data.check = !data.check
  checkedIds.value = []
  updateParentCheckedStatus(item)
  checkChildren(data)
  for (let item of threeData.value) {
    collectCheckedIds(item)
  }
  roleFrom.value.menuIds = checkedIds.value
  const allUnchecked = item.children.every(item => !item.check)
  if (allUnchecked) {
    item.check = false
  } else {
    item.check = true
  }
}
//三级
const sonClick = (item, data, one) => {
  data.check = !data.check
  checkedIds.value = []
  updateParentCheckedStatus(one)
  for (let item of threeData.value) {
    collectCheckedIds(item)
  }
  roleFrom.value.menuIds = checkedIds.value
  const allUnchecked = item.children.every(item => !item.check)
  if (allUnchecked) {
    item.check = false
  } else {
    item.check = true
  }
}
const updateParentCheckedStatus = node => {
  if (node.children) {
    var anyChildChecked = node.children.some(child => {
      if (child.children) {
        updateParentCheckedStatus(child) // 递归处理子节点
      }
      return child.check
    })
    node.check = anyChildChecked
  }
}
const getUserDetail = data => {
  apiList.userDetail(data.userId).then(res => {
    if (res.data) {
      form.value = {
        nickName: res.data.nickName,
        phonenumber: res.data.phonenumber,
        sex: res.data.sex == 0 ? '男' : '女',
        status: res.data.status == 0 ? '正常' : '停用',
        roleIds: res.data.roles.map(res => res.roleId),
        remark: res.data.remark,
        email: res.data.email,
        userId: res.data.userId,
        userName: res.data.userName
      }
    }
  })
}
const getAuthorization = data => {
  apiList.getTreeselect().then(res => {
    for (let i = 0; i < res.data.length; i++) {
      res.data[i].check = false
      res.data[i].expanded = false
      for (let j = 0; j < res.data[i].children.length; j++) {
        res.data[i].children[j].check = false
        res.data[i].children[j].expanded = false
        if (res.data[j].children) {
          for (let item of res.data[j].children) {
            item.check = false
          }
        }
      }
    }
    threeData.value = res.data
    if (data && res.code == 200) {
      setTimeout(() => {
        getRoleMenuTreeselect(data)
      }, 100)
    }
  })
}
const getRoleDetails = data => {
  apiList.roleDetails(data.roleId).then(res => {
    roleFrom.value = {
      roleName: res.data.roleName,
      roleSort: res.data.roleSort,
      roleId: res.data.roleId,
      roleKey: res.data.roleKey,
      menuIds: []
    }
  })
}
// 判断子级内的 check 是否全部为 true
const areAllChildrenChecked = node => {
  // 如果没有子节点，则返回当前节点的 check 状态
  if (!node.children || node.children.length === 0) {
    return node.check
  }

  // 遍历所有子节点，递归判断子节点的 check 状态
  for (let child of node.children) {
    if (!areAllChildrenChecked(child)) {
      return false // 如果有一个子节点的 check 不为 true，则返回 false
    }
  }

  return true // 所有子节点的 check 都为 true，则返回 true
}
const getRoleMenuTreeselect = data => {
  apiList.roleMenuTreeselect(data.roleId).then(res => {
    roleFrom.value.menuIds = res.checkedKeys
    console.log(res.checkedKeys)

    for (let item of res.checkedKeys) {
      for (let self of threeData.value) {
        if (self.id == item) {
          self.check = true
          if (self.check) {
            self.expanded = true
          }
        }
        for (let child of self.children) {
          if (child.id == item) {
            child.check = true
            if (child.check) {
              child.expanded = true
            }
          }
          if (child.children) {
            for (let val of child.children) {
              if (val.id == item) {
                val.check = true
                if (val.check) {
                  val.expanded = true
                }
              }
            }
          }
        }
      }
    }
    for (let item of threeData.value) {
      const isAllChildrenChecked = areAllChildrenChecked(item)
      if (isAllChildrenChecked) {
        item.check = true
      }
    }
  })
}
const handleStationDialogVisible = (visible, { data, type, operation }) => {
  dialogVisible.value = visible
  category.value = type
  operationTypre.value = operation
  initForm()
  getRolelistData()
  if (data && type == 'user') {
    getUserDetail(data)
  } else if (data && type == 'role') {
    getRoleDetails(data)
    getAuthorization(data)
  } else {
    getAuthorization()
  }
}
const sure = () => {
  if (category.value == 'user') {
    if (operationTypre.value == 'edit') {
      if (!form.value.nickName) {
        ElMessage.error('用户名不能为空')
        return
      }
      form.value.sex = form.value.sex == '男' ? 0 : 1
      form.value.status = form.value.status == '正常' ? 0 : 1
      apiList.editUser(form.value).then(res => {
        if (res.code == 200) {
          ElMessage.success('用户编辑成功')
          dialogVisible.value = false
          useEventBus('handleRefreshData').emit(category.value)
        } else {
          ElMessage.error(res.msg)
        }
      })
    } else if (operationTypre.value == 'add') {
      if (!addForm.value.userName) {
        ElMessage.error('账号不能为空')
        return
      }
      if (!addForm.value.password) {
        ElMessage.error('密码不能为空')
        return
      }
      if (!form.value.nickName) {
        ElMessage.error('用户不能为空')
        return
      }
      let obj = {
        ...addForm.value,
        email: form.value.email,
        nickName: form.value.nickName,
        phonenumber: form.value.phonenumber,
        roleIds: form.value.roleIds,
        sex: form.value.sex
      }
      apiList.addUser(obj).then(res => {
        if (res.code == 200) {
          ElMessage.success('用户添加成功')
          dialogVisible.value = false
          useEventBus('handleRefreshData').emit(category.value)
        } else {
          ElMessage.error(res.msg)
        }
      })
    }
  } else {
    if (!roleFrom.value.roleName) {
      ElMessage.error('角色名称不能为空')
      return
    }
    if (!roleFrom.value.roleSort) {
      ElMessage.error('排序不能为空')
      return
    }
    if (!roleFrom.value.roleKey) {
      ElMessage.error('角色标识不能为空')
      return
    }

    if (operationTypre.value == 'edit') {
      apiList.editRole(roleFrom.value).then(res => {
        if (res.code == 200) {
          ElMessage.success('角色编辑成功')
          dialogVisible.value = false
          useEventBus('handleRefreshData').emit(category.value)
        } else {
          ElMessage.error(res.msg)
        }
      })
    } else if (operationTypre.value == 'add') {
      if (roleFrom.value.status != 0 && roleFrom.value.status != 1) {
        ElMessage.error('状态不能为空')
        return
      }
      apiList.addRole(roleFrom.value).then(res => {
        if (res.code == 200) {
          ElMessage.success('角色添加成功')
          dialogVisible.value = false
          useEventBus('handleRefreshData').emit(category.value)
        } else {
          ElMessage.error(res.msg)
        }
      })
    }
  }
}

useEventBus('handleStationDialogVisible').on(handleStationDialogVisible)
const initForm = () => {
  form.value = {
    nickName: '',
    phonenumber: '',
    sex: '',
    status: '',
    roleIds: '',
    remark: '',
    email: '',
    userId: '',
    userName: ''
  }
  addForm.value = {
    email: '',
    nickName: '',
    password: '',
    phonenumber: '',
    roleIds: '',
    sex: '',
    userName: ''
  }
  roleFrom.value = {
    roleName: '',
    roleSort: '',
    roleKey: '',
    roleId: '',
    menuIds: []
  }
}
const handleDialogClose = () => {
  dialogVisible.value = false
}
onMounted(() => {})
</script>

<style scoped lang="scss">
.dialog-header {
  width: 96%;
  height: 47px;
  border-bottom: 1px solid #094976;
  font-weight: 300;
  font-size: 18px;
  color: #ffffff;
  line-height: 47px;
  text-align: left;
  padding-left: 21px;
}
.dialog-content {
  width: 100%;
  min-height: 255px;
  padding-top: 21px;
  .row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .authorization {
      width: 433px;
      height: 135px;
      background: #00233a;
      border-radius: 3px 3px 3px 3px;
      border: 1px solid #00a6d9;
      overflow-y: auto;
      padding-left: 17px;
      padding-top: 5px;
      box-sizing: border-box;
      .parent {
        line-height: 2;
        font-size: 14px;
        color: #fff;
        .icon {
          width: 8px;
          height: 4px;
          margin-bottom: 4px;
          margin-right: 8px;
          cursor: pointer;
        }
        .checkout {
          width: 12px;
          height: 12px;
          margin-right: 5px;
        }
        .parentCheck {
          display: inline-block;
          cursor: pointer;
        }
        label {
          cursor: pointer;
        }
      }

      .children {
        padding-left: 40px;
        .checkout {
          width: 12px;
          height: 12px;
        }
      }
    }
  }
  .multipleRow {
    width: 100%;
    display: block;
    :deep(.el-select) {
      width: 100%;
    }
    .el-form-item {
      width: 100%;
    }
    .el-form-item__content {
      width: 500px;
    }
  }
}
.dialog-bottom {
  width: 100%;
  height: 36px;
  display: flex;
  justify-content: space-evenly;
  div {
    width: 79px;
    height: 36px;
    background: #000000;
    box-shadow: inset 0px 0px 22px 1px #006888;
    border-radius: 6px 6px 6px 6px;
    border: 1px solid #007588;
    font-weight: 300;
    font-size: 14px;
    color: #ffffff;
    line-height: 36px;
    text-align: center;
    cursor: pointer;
  }
  div:first-child {
    background: #004155;
    box-shadow: inset 0px 0px 22px 1px #00c4ff;
    border-radius: 6px 6px 6px 6px;
    border: 1px solid #00cff0;
  }
}
</style>
<style lang="scss">
.edit-dialog {
  min-height: 400px;
  background: rgba(0, 13, 35, 0.84);
  box-shadow: 0px 0px 38px 1px rgba(0, 204, 255, 0.26),
    inset 0px 0px 27px 1px #00d5ff;
  border-radius: 4px 4px 4px 4px;
  border: 1px solid #00a8ff;
  padding: 13px;
  box-sizing: border-box;
  .el-dialog__header {
    padding: 0;
    .el-dialog__headerbtn {
      width: 19px;
      height: 19px;
      background: url(./images/close.png) no-repeat;
      background-size: 100% 100%;
      margin-top: 15px;
      margin-right: 15px;
    }
  }
  .el-dialog__body {
    padding: 0;
  }
  .el-form-item__label {
    font-weight: 500;
    font-size: 16px;
    color: #afd8e5;
  }
  .el-input__wrapper {
    background-color: transparent;
    box-shadow: 1px 1px 1px transparent;
    border-radius: 3px;
    border: 1px solid #00a6d9;
  }
  .el-input__inner {
    color: #fff;
  }
  .el-form-item__content {
    width: 195px;
  }
}
</style>
